package hn.cch.mybatis.service.impl;

import hn.cch.mybatis.entity.TableEntity;
import hn.cch.mybatis.mapper.TableMapper;
import hn.cch.mybatis.service.TableService;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import java.io.IOException;

@Service
public class TableServiceImpl implements TableService {

    private static final Logger logger = LoggerFactory.getLogger(TableServiceImpl.class);

    @Autowired
    private TableMapper tableMapper;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private PlatformTransactionManager transactionManager;


    public void testCursor(Cursor<?> cursor) {
        assert cursor != null;

        if (cursor.isOpen()) {
            logger.info("read cursor isOpen");
        }

        cursor.forEach(tableEntity -> {
            logger.info("getCurrentIndex:{}", cursor.getCurrentIndex());
        });

        if (cursor.isConsumed()) {
            logger.info("read cursor isConsumed");
        }
    }

    /**
     * Mapper接口方法执行完成后数据库连接自动关闭
     */
    @Transactional
    public void testMapper() {
        try (Cursor<TableEntity> cursor = tableMapper.selectTableCursor();) {
            testCursor(cursor);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * SqlSessionFactory
     */
    public void testSqlSessionFactory() {

        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            TableMapper tableMapper = sqlSession.getMapper(TableMapper.class);
            try (Cursor<TableEntity> cursor = tableMapper.selectTableCursor();) {
                testCursor(cursor);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

           // sqlSession.getConfiguration().newStatementHandler(tableMapper, null, null);

        }
    }

    /**
     * TransactionTemplate
     */
    public void testTransactionTemplate() {

        TransactionTemplate transactionTemplate =
                new TransactionTemplate(transactionManager);
        transactionTemplate.execute(status -> {
            try (Cursor<TableEntity> cursor = tableMapper.selectTableCursor();) {
                testCursor(cursor);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return null;
        });

    }


}
